package com.sojson.util.mq.rabbit.immit.config;

import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory.ConfirmType;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

import com.sojson.util.mq.rabbit.code.RabbitChannelUtil;
import com.sojson.util.mq.rabbit.condition.RabbitCondittion;
import com.sojson.util.mq.rabbit.interfaces.IRabbitBaseConsumeUtil;

/**
 * Rabbit配置类
 * 
 * @author liu
 * @date 2022-06-20
 */
@Configuration
@SuppressWarnings("unused")
/** 是否注入这个Bean */
@Conditional(RabbitCondittion.class)
public class RabbitConfig {

    /** Rabbit连接工厂Bean名称(非自动确认发布) */
    private static final String FACTORY_KEY = "rabbitFactory";
    /** Rabbit连接工厂Bean名称(自动确认发布) */
    private static final String FACTORY_KEY_AUTO = "rabbitFactoryAuto";
    /** Rabbit订阅监听消费消息 Bean名称 */
    public static final String LISTENER_KEY = "rabbitListener";

    /**
     * Rabbit连接工厂(非自动确认发布)
     *
     * @return
     */
    @Bean
    public CachingConnectionFactory rabbitFactory() {
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setAddresses(RabbitChannelUtil.ADDRESSES);
        factory.setUsername(RabbitChannelUtil.USERNAME);
        factory.setPassword(RabbitChannelUtil.PASSWORD);
        // factory.setVirtualHost(RabbitChannelUtil.USERNAME);
        return factory;
    }

    /**
     * 用于发送和接收消息(非自动确认发布)</BR>
     *
     * @param factory
     * @return
     */
    @Bean
    public RabbitTemplate rabbitTemplate(@Qualifier(FACTORY_KEY) CachingConnectionFactory factory) {
        RabbitTemplate template = new RabbitTemplate(factory);
        // 若使用confirm-callback或return-callback,必须要配置setPublisherReturns为true
        factory.setPublisherReturns(true);

        // 开启发布者确认模式,设置发布者确认的类型
        // 若使用confirm-callback或waitForConfirms,必须要开启发布者确认模式
        factory.setPublisherConfirmType(ConfirmType.SIMPLE);
        /// // 全局ConfirmCallback(每个RabbitTemplate只能有一个)
        /// template.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
        /// @Override
        /// public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        /// System.out.println("ConfirmCallback:-数据：" + correlationData);
        /// System.out.println("ConfirmCallback:-是否成功：" + ack);
        /// System.out.println("ConfirmCallback:-原因：" + cause);
        /// }
        /// });

        /// // 开启消息故障检测模式
        /// // 若使用return-callback,必须要配置setMandatory为true
        /// template.setMandatory(true);
        /// // 全局ReturnsCallback(每个RabbitTemplate只能有一个)
        /// template.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
        /// @Override
        /// public void returnedMessage(ReturnedMessage returned) {
        /// System.out.println("ReturnCallback:-消息：" + returned.getMessage());
        /// System.out.println("ReturnCallback:-回应码：" + returned.getReplyCode());
        /// System.out.println("ReturnCallback:-回应信息：" + returned.getReplyText());
        /// System.out.println("ReturnCallback:-交换机：" + returned.getExchange());
        /// System.out.println("ReturnCallback:-路由键：" + returned.getRoutingKey());
        /// }
        /// });
        return template;
    }

    /// /**
    /// * Rabbit连接工厂(自动确认发布)
    /// *
    /// * @return
    /// */
    /// @Bean
    /// @Primary
    /// public CachingConnectionFactory rabbitFactoryAuto() {
    /// CachingConnectionFactory factory = new CachingConnectionFactory();
    /// factory.setHost(RabbitChannelUtil.HOST);
    /// factory.setPort(RabbitChannelUtil.PORT);
    /// factory.setUsername(RabbitChannelUtil.USERNAME);
    /// factory.setPassword(RabbitChannelUtil.PASSWORD);
    ///
    /// // 设置发布者确认的类型
    /// factory.setPublisherConfirmType(ConfirmType.NONE);
    /// // factory.setVirtualHost(RabbitChannelUtil.USERNAME);
    /// return factory;
    /// }
    ///
    /// /**
    /// * 用于发送和接收消息(自动确认发布)</BR>
    /// *
    /// * @param connectionFactory
    /// * @return
    /// */
    /// @Bean
    /// @Primary
    /// public RabbitTemplate rabbitTemplateAuto(@Qualifier(FACTORY_KEY_AUTO) CachingConnectionFactory factory) {
    /// RabbitTemplate template = new RabbitTemplate(factory);
    /// return template;
    /// }

    /**
     * 用于订阅监听消费消息</BR>
     * 
     * @param connectionFactory
     * @return
     */
    @Bean
    public SimpleRabbitListenerContainerFactory
        rabbitListener(SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory factory) {
        SimpleRabbitListenerContainerFactory listener = new SimpleRabbitListenerContainerFactory();
        configurer.configure(listener, factory);

        // 初始化参数
        init(listener);
        return listener;
    }

    /**
     * 对交换机,队列,以及绑定等进行相关的操作</BR>
     * 
     * @param rabbitFactory
     * @return
     */
    @Bean
    public AmqpAdmin amqpAdmin(ConnectionFactory rabbitFactory) {
        return new RabbitAdmin(rabbitFactory);
    }

    /**
     * 初始化参数
     * 
     * @param listener
     */
    private void init(SimpleRabbitListenerContainerFactory listener) {
        // 默认消费者数量
        // listener.setConcurrentConsumers(5);
        // 最大消费者数量
        // listener.setMaxConcurrentConsumers(10);
        // 每次给消费者发送的消息数量
        listener.setPrefetchCount(IRabbitBaseConsumeUtil.PREFETCH_COTCHUNT);
    }

}